<?php

class Ws
{
    public $server;
    public $redis = null;
    public $timer_id = 0;
    public function __construct()
    {
        $this->server = new Swoole\WebSocket\Server("0.0.0.0", 9501);
        $this->redis = new \Redis();

// 连接到Redis服务器
        $this->redis->connect('127.0.0.1', 6379);
        //监听ws连接事件
        $this->server->on('open',[$this,'onOpen']);
        $this->server->on('message',[$this,'onMessage']);
        $this->server->on('close',[$this,'onClose']);
        //$this->server->on('request',[$this,'onRequest']);

        $this->server->start();


        /* $this->server->on('open', function (Swoole\WebSocket\Server $server, $request) {
             echo "server: handshake success with fd{$request->fd}\n";
         });
         //监听ws消息事件
         $this->server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
             $data = json_decode($frame->data,true);
             print_r($data);
             echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
             $server->push($frame->fd, "this is server");
         });
         $this->server->on('close', function ($ser, $fd) {
             echo "client {$fd} closed\n";
         });
         $this->server->on('request', function ($request, $response) {
             echo '进到这里了';
             // 接收http请求从get获取message参数的值，给用户推送
             // $this->server->connections 遍历所有websocket连接用户的fd，给所有用户推送
             foreach ($this->server->connections as $fd) {
                 // 需要先判断是否是正确的websocket连接，否则有可能会push失败
                 if ($this->server->isEstablished($fd)) {
                     $data = json_decode($request->get['message'],true);
                     print_r($data);
                     $this->server->push($fd, '你好');
                 }
             }
         });
         $this->server->start();*/
    }

    public function onOpen($server,$request)
    {
        //echo "server: handshake success with fd{$request->fd}\n";
        /*$arr = [
            'type'=>1,
            'fd'=>  $request->fd,
        ];
        $data = json_encode($arr);
        $this->server->push($request->fd, $data);*/
        //设置一个定时器
        /*$this->timer_id = Swoole\Timer::tick(2000,function($timer_id){
            echo '2s:timerId:'.$timer_id."\n";
        });
        echo 'timer_id:'.$this->timer_id."\n";*/
    }
    function valueExistsInList($redis, $listName, $value) {
        $length = $redis->lLen($listName); // 获取列表长度
        for ($i = 0; $i < $length; $i++) {
            if ($redis->lIndex($listName, $i) === $value) {
                return true; // 找到值
            }
        }
        return false; // 未找到值
    }
    public function onMessage($server,$frame)
    {
        //$data = $frame->data;
        $data = json_decode($frame->data,true);
        
        if($data['type']=='init')
        {
            $userId = 'fd:'.$frame->fd;
            $name = $data['name'];
            $this->redis->set($userId,$name);//用户信息
            $this->redis->expire($userId, 60*60*24);
            $user_list = [];
            if (!$this->valueExistsInList($this->redis, 'user_list', $name)) {
                $this->redis->lpush('user_list', $name);//redis 保存用户列表
            }
            $list = $this->redis->lrange('user_list', 0, -1);
             $arr = [
                'type'=>4,
                'fd'  =>$frame->fd,
                'name'=>$data['name'],
                'data'=>$list,
                'createtime'=>date('Y-m-d H:i',time())
            ];
            
        }
        else if($data['type']=='bq')
        {
            $arr = [
                'type'=>5,
                'fd'  =>$frame->fd,
                'name'=>$data['name'],
                'data'=>$data['data'],
                'createtime'=>date('Y-m-d H:i',time())
            ];
            //清除定时器
            if($this->timer_id!=0)
            {
                Swoole\Timer::clear($this->timer_id);
                echo "清除了定时任务：".$this->timer_id."\n";
            }

        }
        else
        {
            $arr = [
                'type'=>2,
                'fd'  =>$frame->fd,
                'name'=>$data['name'],
                'data'=>$data['data'],
                'createtime'=>date('Y-m-d H:i',time())
            ];
        }
         $data = json_encode($arr);
            foreach ($this->server->connections as $fd) {
                // 需要先判断是否是正确的websocket连接，否则有可能会push失败

                if ($this->server->isEstablished($fd)) {
                    $this->server->push($fd, $data);
                }
            }
        //print_r($data);
        //echo "receive from {$frame->fd}:{$data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
        //echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
        //$server->push($frame->fd, "this is server");

    }

    public function onClose($server,$fd)
    {


        $userId = 'fd:'.$fd;
        $name = $this->redis->get($userId);
        $user_list = [];
      
        
            
        $this->redis->lRem('user_list', $name, 1);//删除用户列表
        $user_name = $this->redis->del($userId);//删除用户信息
        $list = $this->redis->lrange('user_list', 0, -1);
        $arr = [
            'type'=>3,
            'fd'  =>$fd,
            'createtime'=>date('Y-m-d H:i',time()),
            'name'  =>$name,
            'data'=>$list,
        ];
        $data = json_encode($arr);
        foreach ($this->server->connections as $fd) {
            // 需要先判断是否是正确的websocket连接，否则有可能会push失败
            if ($this->server->isEstablished($fd)) {
                $this->server->push($fd, $data);
            }
        }
        echo "client {$fd} closed\n";
    }

    /*public function onRequest($request, $response)
    {
        echo '进到这里了';
        // 接收http请求从get获取message参数的值，给用户推送
        // $this->server->connections 遍历所有websocket连接用户的fd，给所有用户推送
        foreach ($this->server->connections as $fd) {
            // 需要先判断是否是正确的websocket连接，否则有可能会push失败
            $data = json_decode( $request->get['message'],true);
            if ($this->server->isEstablished($fd)) {
                $this->server->push($fd, $data);
            }
        }
    }*/
}

new Ws();
